package org.zhtkj.web.controller;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Arrays;

import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.zhtkj.framework.message.PackageData;
import org.zhtkj.framework.session.Session;
import org.zhtkj.framework.session.SessionManager;
import org.zhtkj.web.config.Charsets;
import org.zhtkj.web.endpoint.JT808Endpoint;
import org.zhtkj.web.jt808.common.JT808MessageCode;
import org.zhtkj.web.jt808.dto.CallPhone;
import org.zhtkj.web.jt808.dto.CameraShot;
import org.zhtkj.web.jt808.dto.CommonResult;
import org.zhtkj.web.jt808.dto.DriverIdentityInfo;
import org.zhtkj.web.jt808.dto.DriverIdentityInfoQuery;
import org.zhtkj.web.jt808.dto.DriverIdentityInfoQueryReply;
import org.zhtkj.web.jt808.dto.DriverIdentityInfoRemove;
import org.zhtkj.web.jt808.dto.DriverIdentityInfoSetting;
import org.zhtkj.web.jt808.dto.ElectronWayBill;
import org.zhtkj.web.jt808.dto.ElectronWayBillQuery;
import org.zhtkj.web.jt808.dto.ElectronWayBillQueryReply;
import org.zhtkj.web.jt808.dto.ElectronWayBillRemove;
import org.zhtkj.web.jt808.dto.ElectronWayBillSetting;
import org.zhtkj.web.jt808.dto.EventSetting;
import org.zhtkj.web.jt808.dto.Information;
import org.zhtkj.web.jt808.dto.MapFence;
import org.zhtkj.web.jt808.dto.MapFencePolygonSetting;
import org.zhtkj.web.jt808.dto.MapFenceRectangle;
import org.zhtkj.web.jt808.dto.MapFenceRemove;
import org.zhtkj.web.jt808.dto.MapFenceRound;
import org.zhtkj.web.jt808.dto.MapFenceRouteClear;
import org.zhtkj.web.jt808.dto.MapFenceSetting;
import org.zhtkj.web.jt808.dto.MediaDataQuery;
import org.zhtkj.web.jt808.dto.MediaDataQueryReply;
import org.zhtkj.web.jt808.dto.MediaDataReportRequest;
import org.zhtkj.web.jt808.dto.MessageSubSetting;
import org.zhtkj.web.jt808.dto.ParameterQuery;
import org.zhtkj.web.jt808.dto.ParameterQueryReply;
import org.zhtkj.web.jt808.dto.ParameterQuerySome;
import org.zhtkj.web.jt808.dto.ParameterSetting;
import org.zhtkj.web.jt808.dto.PassthroughPack;
import org.zhtkj.web.jt808.dto.PhoneBook;
import org.zhtkj.web.jt808.dto.PositionReply;
import org.zhtkj.web.jt808.dto.QuestionMessage;
import org.zhtkj.web.jt808.dto.RSAPack;
import org.zhtkj.web.jt808.dto.RouteRemove;
import org.zhtkj.web.jt808.dto.RouteSetting;
import org.zhtkj.web.jt808.dto.ScreenInfo;
import org.zhtkj.web.jt808.dto.ScreenInfoQuery;
import org.zhtkj.web.jt808.dto.ScreenInfoQueryReply;
import org.zhtkj.web.jt808.dto.ScreenInfoRemove;
import org.zhtkj.web.jt808.dto.ScreenInfoSetting;
import org.zhtkj.web.jt808.dto.SoundRecord;
import org.zhtkj.web.jt808.dto.TemporaryMonitor;
import org.zhtkj.web.jt808.dto.TerminalControl;
import org.zhtkj.web.jt808.dto.TerminalParameter;
import org.zhtkj.web.jt808.dto.TerminalUpgradePack;
import org.zhtkj.web.jt808.dto.TerminalUpgradePackSub;
import org.zhtkj.web.jt808.dto.TextMessage;
import org.zhtkj.web.jt808.dto.VehicleControl;
import org.zhtkj.web.jt808.dto.basics.Header;
import org.zhtkj.web.utils.MediaPacketUtils;
import org.zhtkj.web.utils.MediaPacketUtils.ActionInfo;

import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;

@Controller
@RequestMapping
public class TerminalController {

    @Value("${terminal.upgrade.uri}")
    private String uri;
    
    @Autowired
    private JT808Endpoint endpoint;

    @Autowired
    private SessionManager sessionManager;
    
    @ApiOperation(value = "设置终端参数")
    @RequestMapping(value = "{terminalId}/setParameters", method = RequestMethod.POST)
    @ResponseBody
    public CommonResult setParameters(@PathVariable("terminalId") String terminalId, @RequestBody ParameterSetting body) {
    	CommonResult response = new CommonResult();
    	Session session = sessionManager.findByTerminalId(terminalId);
    	if (session != null && session.getChannel().isWritable()) {
            body.setHeader(new Header(JT808MessageCode.设置终端参数, terminalId));
            endpoint.send(body, false);
            response.setResultCode(CommonResult.Success);
    	} else {
    		response.setResultCode(CommonResult.Fail);
    	}
        return response;
    }

    @ApiOperation(value = "查询终端参数")
    @RequestMapping(value = "{terminalId}/findParameters", method = RequestMethod.POST)
    @ResponseBody
    public ParameterQueryReply findParameters(@PathVariable("terminalId") String terminalId) {
    	ParameterQuery body = new ParameterQuery();
        body.setHeader(new Header(JT808MessageCode.查询终端参数, terminalId));
        ParameterQueryReply response = (ParameterQueryReply) endpoint.send(body);
        return response;
    }

    @ApiOperation(value = "查询指定终端参数")
    @RequestMapping(value = "{terminalId}/findParametersSome", method = RequestMethod.POST)
    @ResponseBody
    public ParameterQueryReply findParametersSome(@PathVariable("terminalId") String terminalId, @ApiParam("终端参数ID列表") @RequestBody Integer[] idList) {
		ParameterQuerySome body = new ParameterQuerySome();
    	for (Integer id: idList) {
    		body.addTerminalParameter(new TerminalParameter(id));
    	}
        body.setHeader(new Header(JT808MessageCode.查询指定终端参数, terminalId));
        ParameterQueryReply response = (ParameterQueryReply) endpoint.send(body);
        return response;
    }
    
    @ApiOperation(value = "终端控制")
    @RequestMapping(value = "{terminalId}/control/terminal", method = RequestMethod.POST)
    @ResponseBody
    public CommonResult terminalControl(@PathVariable("terminalId") String terminalId, @RequestBody TerminalControl body) {
    	CommonResult response = new CommonResult();
    	Session session = sessionManager.findByTerminalId(terminalId);
    	if (session != null && session.getChannel().isWritable()) {
            body.setHeader(new Header(JT808MessageCode.终端控制, terminalId));
            endpoint.send(body, false);
            response.setResultCode(CommonResult.Success);
    	} else {
    		response.setResultCode(CommonResult.Fail);
    	}
        return response;
    }

    @ApiOperation(value = "位置信息查询")
    @RequestMapping(value = "{terminalId}/position", method = RequestMethod.POST)
    @ResponseBody
    public PositionReply findPosition(@PathVariable("terminalId") String terminalId) {
        PackageData<Header> body = new PackageData<Header>();
        body.setHeader(new Header(JT808MessageCode.位置信息查询, terminalId));
        PositionReply response = (PositionReply) endpoint.send(body);
        return response;
    }

    @ApiOperation(value = "临时位置跟踪控制")
    @RequestMapping(value = "{terminalId}/track", method = RequestMethod.POST)
    @ResponseBody
    public CommonResult temporaryTrackControl(@PathVariable("terminalId") String terminalId, @RequestBody TemporaryMonitor body) {
    	CommonResult response = new CommonResult();
    	Session session = sessionManager.findByTerminalId(terminalId);
    	if (session != null && session.getChannel().isWritable()) {
            body.setHeader(new Header(JT808MessageCode.临时位置跟踪控制, terminalId));
            endpoint.send(body, false);
            response.setResultCode(CommonResult.Success);
    	} else {
    		response.setResultCode(CommonResult.Fail);
    	}
        return response;
    }

    @ApiOperation(value = "文本信息下发")
    @RequestMapping(value = "{terminalId}/text", method = RequestMethod.POST)
    @ResponseBody
    public CommonResult sendText(@PathVariable("terminalId") String terminalId, @RequestBody TextMessage body) {
    	CommonResult response = new CommonResult();
    	Session session = sessionManager.findByTerminalId(terminalId);
    	if (session != null && session.getChannel().isWritable()) {
            body.setHeader(new Header(JT808MessageCode.文本信息下发, terminalId));
            endpoint.send(body, false);
            response.setResultCode(CommonResult.Success);
    	} else {
    		response.setResultCode(CommonResult.Fail);
    	}
        return response;
    }

    @ApiOperation(value = "事件设置")
    @RequestMapping(value = "{terminalId}/events", method = RequestMethod.POST)
    @ResponseBody
    public CommonResult eventSetting(@PathVariable("terminalId") String terminalId, @RequestBody EventSetting body) {
    	CommonResult response = new CommonResult();
    	Session session = sessionManager.findByTerminalId(terminalId);
    	if (session != null && session.getChannel().isWritable()) {
            body.setHeader(new Header(JT808MessageCode.事件设置, terminalId));
            endpoint.send(body, false);
            response.setResultCode(CommonResult.Success);
    	} else {
    		response.setResultCode(CommonResult.Fail);
    	}
        return response;
    }

    @ApiOperation(value = "提问下发")
    @RequestMapping(value = "{terminalId}/question", method = RequestMethod.POST)
    @ResponseBody
    public CommonResult sendQuestion(@PathVariable("terminalId") String terminalId, @RequestBody QuestionMessage body) {
    	CommonResult response = new CommonResult();
    	Session session = sessionManager.findByTerminalId(terminalId);
    	if (session != null && session.getChannel().isWritable()) {
            body.setHeader(new Header(JT808MessageCode.提问下发, terminalId));
            endpoint.send(body, false);
            response.setResultCode(CommonResult.Success);
    	} else {
    		response.setResultCode(CommonResult.Fail);
    	}
        return response;
    }

    @ApiOperation(value = "信息点播菜单设置")
    @RequestMapping(value = "{terminalId}/information/menu", method = RequestMethod.POST)
    @ResponseBody
    public CommonResult infoMenu(@PathVariable("terminalId") String terminalId, @RequestBody MessageSubSetting body) {
    	CommonResult response = new CommonResult();
    	Session session = sessionManager.findByTerminalId(terminalId);
    	if (session != null && session.getChannel().isWritable()) {
            body.setHeader(new Header(JT808MessageCode.信息点播菜单设置, terminalId));
            endpoint.send(body, false);
            response.setResultCode(CommonResult.Success);
    	} else {
    		response.setResultCode(CommonResult.Fail);
    	}
        return response;
    }

    @ApiOperation(value = "信息服务")
    @RequestMapping(value = "{terminalId}/information/push", method = RequestMethod.POST)
    @ResponseBody
    public CommonResult messageSubSetting(@PathVariable("terminalId") String terminalId, @RequestBody Information body) {
    	CommonResult response = new CommonResult();
    	Session session = sessionManager.findByTerminalId(terminalId);
    	if (session != null && session.getChannel().isWritable()) {
            body.setHeader(new Header(JT808MessageCode.信息服务, terminalId));
            endpoint.send(body, false);
            response.setResultCode(CommonResult.Success);
    	} else {
    		response.setResultCode(CommonResult.Fail);
    	}
        return response;
    }

    @ApiOperation(value = "电话回拨")
    @RequestMapping(value = "{terminalId}/callPhone", method = RequestMethod.POST)
    @ResponseBody
    public CommonResult callPhone(@PathVariable("terminalId") String terminalId, @RequestBody CallPhone body) {
    	CommonResult response = new CommonResult();
    	Session session = sessionManager.findByTerminalId(terminalId);
    	if (session != null && session.getChannel().isWritable()) {
            body.setHeader(new Header(JT808MessageCode.电话回拨, terminalId));
            endpoint.send(body, false);
            response.setResultCode(CommonResult.Success);
    	} else {
    		response.setResultCode(CommonResult.Fail);
    	}
        return response;
    }

    @ApiOperation(value = "设置电话本")
    @RequestMapping(value = "{terminalId}/phoneBook", method = RequestMethod.POST)
    @ResponseBody
    public CommonResult phoneBook(@PathVariable("terminalId") String terminalId, @RequestBody PhoneBook body) {
    	CommonResult response = new CommonResult();
    	Session session = sessionManager.findByTerminalId(terminalId);
    	if (session != null && session.getChannel().isWritable()) {
            body.setHeader(new Header(JT808MessageCode.设置电话本, terminalId));
            endpoint.send(body, false);
            response.setResultCode(CommonResult.Success);
    	} else {
    		response.setResultCode(CommonResult.Fail);
    	}
        return response;
    }

    @ApiOperation(value = "车辆控制")
    @RequestMapping(value = "{terminalId}/vehicle/control", method = RequestMethod.POST)
    @ResponseBody
    public PositionReply vehicleControl(@PathVariable("terminalId") String terminalId, @RequestBody VehicleControl body) {
        body.setHeader(new Header(JT808MessageCode.车辆控制, terminalId));
        PositionReply response = (PositionReply) endpoint.send(body);
        return response;
    }

    @ApiOperation(value = "设置圆形区域")
    @RequestMapping(value = "{terminalId}/mapFenceRound", method = RequestMethod.POST)
    @ResponseBody
    public CommonResult addMapFenceRound(@PathVariable("terminalId") String terminalId, @RequestBody MapFenceSetting<MapFenceRound> body) {
    	CommonResult response = new CommonResult();
    	Session session = sessionManager.findByTerminalId(terminalId);
    	if (session != null && session.getChannel().isWritable()) {
            body.setHeader(new Header(JT808MessageCode.设置圆形区域, terminalId));
            endpoint.send(body, false);
            response.setResultCode(CommonResult.Success);
    	} else {
    		response.setResultCode(CommonResult.Fail);
    	}
        return response;
    }
    
    @ApiOperation(value = "设置矩形区域")
    @RequestMapping(value = "{terminalId}/mapFenceRectangle", method = RequestMethod.POST)
    @ResponseBody
    public CommonResult addMapFenceRectangle(@PathVariable("terminalId") String terminalId, @RequestBody MapFenceSetting<MapFenceRectangle> body) {
    	CommonResult response = new CommonResult();
    	Session session = sessionManager.findByTerminalId(terminalId);
    	if (session != null && session.getChannel().isWritable()) {
            body.setHeader(new Header(JT808MessageCode.设置矩形区域, terminalId));
            endpoint.send(body, false);
            response.setResultCode(CommonResult.Success);
    	} else {
    		response.setResultCode(CommonResult.Fail);
    	}
        return response;
    }
    
    @ApiOperation(value = "设置多边形区域")
    @RequestMapping(value = "{terminalId}/mapFencePolygon", method = RequestMethod.POST)
    @ResponseBody
    public CommonResult addMapFencePolygon(@PathVariable("terminalId") String terminalId, @RequestBody MapFencePolygonSetting body) {
    	CommonResult response = new CommonResult();
    	Session session = sessionManager.findByTerminalId(terminalId);
    	if (session != null && session.getChannel().isWritable()) {
            body.setHeader(new Header(JT808MessageCode.设置多边形区域, terminalId));
            endpoint.send(body, false);
            response.setResultCode(CommonResult.Success);
    	} else {
    		response.setResultCode(CommonResult.Fail);
    	}
        return response;
    }
    
    @ApiOperation(value = "删除区域")
    @RequestMapping(value = "{terminalId}/mapFence/remove/{type}", method = RequestMethod.POST)
    @ResponseBody
    public CommonResult removeMapFence(@PathVariable("terminalId") String terminalId,
                                       @ApiParam("区域类型:1.圆形 2.矩形 3.多边形") @PathVariable("type") int type,
                                       @ApiParam("区域ID列表") @RequestBody Long[] idList) {
    	CommonResult response = new CommonResult();
    	Session session = sessionManager.findByTerminalId(terminalId);
    	if (session != null && session.getChannel().isWritable()) {
            MapFenceRemove<Header> body = new MapFenceRemove<Header>();
            switch (type) {
                case 1:
                    body.setHeader(new Header(JT808MessageCode.删除圆形区域, terminalId));
                    break;
                case 2:
                    body.setHeader(new Header(JT808MessageCode.删除矩形区域, terminalId));
                    break;
                case 3:
                    body.setHeader(new Header(JT808MessageCode.删除多边形区域, terminalId));
                    break;
                default:
                    return null;
            }
            for (Long id: idList) {
            	MapFence mapFence = new MapFence(id);
            	body.addMapFence(mapFence);
            }
            endpoint.send(body, false);
            response.setResultCode(CommonResult.Success);
    	} else {
    		response.setResultCode(CommonResult.Fail);
    	}
        return response;
    }
    
    @ApiOperation(value = "设置路线")
    @RequestMapping(value = "{terminalId}/route", method = RequestMethod.POST)
    @ResponseBody
    public CommonResult addRoute(@PathVariable("terminalId") String terminalId, @RequestBody RouteSetting body) {
    	CommonResult response = new CommonResult();
    	Session session = sessionManager.findByTerminalId(terminalId);
    	if (session != null && session.getChannel().isWritable()) {
            body.setHeader(new Header(JT808MessageCode.设置路线, terminalId));
            endpoint.send(body, false);
            response.setResultCode(CommonResult.Success);
    	} else {
    		response.setResultCode(CommonResult.Fail);
    	}
        return response;
    }

    @ApiOperation(value = "删除路线")
    @RequestMapping(value = "{terminalId}/route/remove", method = RequestMethod.POST)
    @ResponseBody
    public CommonResult removeRoute(@PathVariable("terminalId") String terminalId, @ApiParam("路线ID列表") @RequestBody Long[] idList) {
    	CommonResult response = new CommonResult();
    	Session session = sessionManager.findByTerminalId(terminalId);
    	if (session != null && session.getChannel().isWritable()) {
            RouteRemove body = new RouteRemove();
            for (Long id : idList) {
            	RouteSetting routeSetting = new RouteSetting();
            	routeSetting.setId(id);
            	body.addRouteSetting(routeSetting);
            }
            body.setHeader(new Header(JT808MessageCode.删除路线, terminalId));
            endpoint.send(body, false);
            response.setResultCode(CommonResult.Success);
    	} else {
    		response.setResultCode(CommonResult.Fail);
    	}
        return response;
    }

    @ApiOperation(value = "清空区域和路线")
    @RequestMapping(value = "{terminalId}/mapFenceRoute/clear/{command}", method = RequestMethod.POST)
    @ResponseBody
    public CommonResult mapFenceRouteClear(@PathVariable("terminalId") String terminalId,
    		@ApiParam("command，0：清空所有区域和路线  1：清空所有区域  3：清空所有路线") @PathVariable("command") Byte command) {
    	CommonResult response = new CommonResult();
    	Session session = sessionManager.findByTerminalId(terminalId);
    	if (session != null && session.getChannel().isWritable()) {
        	MapFenceRouteClear body = new MapFenceRouteClear();
        	body.setCommand(command.intValue());
        	body.setHeader(new Header(JT808MessageCode.清空区域和路线, terminalId));
            endpoint.send(body, false);
            response.setResultCode(CommonResult.Success);
    	} else {
    		response.setResultCode(CommonResult.Fail);
    	}
        return response;
    }
    
    @ApiOperation(value = "摄像头立即拍摄命令")
    @RequestMapping(value = "{terminalId}/cameraShot", method = RequestMethod.POST)
    @ResponseBody
    public CommonResult cameraShot(@PathVariable("terminalId") String terminalId, @RequestBody CameraShot body) {
    	Session session = sessionManager.findByTerminalId(terminalId);
    	if (session != null && session.getChannel().isWritable()) {
            body.setHeader(new Header(JT808MessageCode.摄像头立即拍摄命令, terminalId));
            CommonResult response = (CommonResult) endpoint.send(body);
            MediaPacketUtils.putAction(terminalId + ":" + response.getFlowId(), new ActionInfo(DateTime.now(), body.getActionId()));
            return response;
    	} else {
    		CommonResult response = new CommonResult();
    		response.setResultCode(CommonResult.Fail);
    		return response;
    	}
    }

    @ApiOperation(value = "存储多媒体数据检索")
    @RequestMapping(value = "{terminalId}/mediaDataQuery", method = RequestMethod.POST)
    @ResponseBody
    public MediaDataQueryReply mediaDataQuery(@PathVariable("terminalId") String terminalId, @RequestBody MediaDataQuery body) {
        body.setHeader(new Header(JT808MessageCode.存储多媒体数据检索, terminalId));
        MediaDataQueryReply response = (MediaDataQueryReply) endpoint.send(body);
        return response;
    }

    @ApiOperation(value = "存储多媒体数据上传命令")
    @RequestMapping(value = "{terminalId}/mediaDataReportRequest", method = RequestMethod.POST)
    @ResponseBody
    public CommonResult mediaDataReportRequest(@PathVariable("terminalId") String terminalId, @RequestBody MediaDataReportRequest body) {
    	CommonResult response = new CommonResult();
    	Session session = sessionManager.findByTerminalId(terminalId);
    	if (session != null && session.getChannel().isWritable()) {
            body.setHeader(new Header(JT808MessageCode.存储多媒体数据上传命令, terminalId));
            endpoint.send(body, false);
            response.setResultCode(CommonResult.Success);
    	} else {
    		response.setResultCode(CommonResult.Fail);
    	}
        return response;
    }

    @ApiOperation(value = "录音开始命令")
    @RequestMapping(value = "{terminalId}/soundRecord", method = RequestMethod.POST)
    @ResponseBody
    public CommonResult soundRecord(@PathVariable("terminalId") String terminalId, @RequestBody SoundRecord body) {
    	CommonResult response = new CommonResult();
    	Session session = sessionManager.findByTerminalId(terminalId);
    	if (session != null && session.getChannel().isWritable()) {
            body.setHeader(new Header(JT808MessageCode.录音开始命令, terminalId));
            endpoint.send(body, false);
            response.setResultCode(CommonResult.Success);
    	} else {
    		response.setResultCode(CommonResult.Fail);
    	}
        return response;
    }

    @ApiOperation(value = "数据下行透传")
    @RequestMapping(value = "{terminalId}/passthrough", method = RequestMethod.POST)
    @ResponseBody
    public CommonResult passthrough(@PathVariable("terminalId") String terminalId, @RequestBody PassthroughPack body) {
    	CommonResult response = new CommonResult();
    	Session session = sessionManager.findByTerminalId(terminalId);
    	if (session != null && session.getChannel().isWritable()) {
            body.setHeader(new Header(JT808MessageCode.数据下行透传, terminalId));
            endpoint.send(body, false);
            response.setResultCode(CommonResult.Success);
    	} else {
    		response.setResultCode(CommonResult.Fail);
    	}
        return response;
    }

    @ApiOperation(value = "平台RSA公钥")
    @RequestMapping(value = "{terminalId}/rsaSwap", method = RequestMethod.POST)
    @ResponseBody
    public RSAPack rsaSwap(@PathVariable("terminalId") String terminalId, @RequestBody RSAPack body) {
        body.setHeader(new Header(JT808MessageCode.平台RSA公钥, terminalId));
        RSAPack response = (RSAPack) endpoint.send(body, false);
        return response;
    }
    
    @ApiOperation(value = "下发终端升级包")
    @RequestMapping(value = "{terminalId}/upgrade", method = RequestMethod.POST)
    @ResponseBody
    public CommonResult terminalUpgrade(@PathVariable("terminalId") String terminalId, @RequestBody TerminalUpgradePack body) {
    	CommonResult response = new CommonResult();
    	Session session = sessionManager.findByTerminalId(terminalId);
    	if (session != null && session.getChannel().isWritable()) {
    		File path = new File(uri + File.separator + new String(body.getManufacturerId()));
    		File file = new File(path.getPath() + File.separator + body.getVersion());
    		FileInputStream fis = null;
    		try {
    			fis = new FileInputStream(file);
    			byte[] bts = new byte[fis.available()];
    			fis.read(bts);
    			//需要分包
    			if (bts.length > 800) {
    				//发第一个包
    				Integer packetTotal = (bts.length%800 == 0) ? bts.length/800 : (bts.length/800 + 1);
    				Header header = new Header(JT808MessageCode.下发终端升级包, terminalId);
    				header.setHasSubPackage(true);
    				header.setTotalSubPackage(packetTotal);
    				header.setSubPackageSeq(1);
    				body.setHeader(header);
    				body.setVersionLen(body.getVersion().getBytes(Charsets.GBK).length);
    				body.setPacketLen(bts.length);
    				body.setPacket(Arrays.copyOfRange(bts, 0, 800));
    				endpoint.send(body, false);
    				//发其他的子包
    				for (int i = 2; i <= packetTotal; i++) {
    					Header subHeader = new Header(JT808MessageCode.下发终端升级包, terminalId);
    					TerminalUpgradePackSub subBody = new TerminalUpgradePackSub();
    					subHeader.setTerminalPhone(header.getTerminalPhone());
    					subHeader.setType(header.getType());
    					subHeader.setHasSubPackage(true);
    					subHeader.setTotalSubPackage(packetTotal);
    					subHeader.setSubPackageSeq(i);
    					subBody.setHeader(subHeader);
    					if (i != packetTotal) {
    						subBody.setPacket(Arrays.copyOfRange(bts, (i - 1)*800, i*800));
    					} else {
    						subBody.setPacket(Arrays.copyOfRange(bts, (i - 1)*800, bts.length));
    					}
    					if (i == packetTotal) {
    						endpoint.send(subBody, false);
    					} else {
    						endpoint.send(subBody, false);
    					}
    				}
    			} else { //不用分包
    				body.setVersionLen(body.getVersion().getBytes().length);
    				body.setPacketLen(bts.length);
    				body.setPacket(bts);
    				body.setHeader(new Header(JT808MessageCode.下发终端升级包, terminalId));
    		        endpoint.send(body, false);
    			}
    		} catch (Exception e) {
    			e.printStackTrace();
    		} finally {
    			if (fis != null) {
    				try {
    					fis.close();
    				} catch (IOException e) {
    					e.printStackTrace();
    				}
    			}
    		}
            response.setResultCode(CommonResult.Success);
    	} else {
    		response.setResultCode(CommonResult.Fail);
    	}
    	return response;
    }
    
    @ApiOperation(value = "电子运单设置")
    @RequestMapping(value = "{terminalId}/electronWayBillSetting", method = RequestMethod.POST)
    @ResponseBody
    public CommonResult electronWayBillSetting(@PathVariable("terminalId") String terminalId, @RequestBody ElectronWayBillSetting body) {
    	CommonResult response = new CommonResult();
    	Session session = sessionManager.findByTerminalId(terminalId);
    	if (session != null && session.getChannel().isWritable()) {
            body.setHeader(new Header(JT808MessageCode.电子运单设置, terminalId));
            endpoint.send(body, false);
            response.setResultCode(CommonResult.Success);
    	} else {
    		response.setResultCode(CommonResult.Fail);
    	}
        return response;
    }
    
    @ApiOperation(value = "电子运单删除")
    @RequestMapping(value = "{terminalId}/electronWayBillRemove", method = RequestMethod.POST)
    @ResponseBody
    public CommonResult electronWayBillRemove(@PathVariable("terminalId") String terminalId, @ApiParam("电子运单ID列表") @RequestBody Integer[] idList) {
    	CommonResult response = new CommonResult();
    	Session session = sessionManager.findByTerminalId(terminalId);
    	if (session != null && session.getChannel().isWritable()) {
        	ElectronWayBillRemove body = new ElectronWayBillRemove();
        	body.setTotal(idList.length);
            for (Integer id: idList) {
            	body.addElectronWayBill(new ElectronWayBill(id));
            }
            body.setHeader(new Header(JT808MessageCode.电子运单删除, terminalId));
            endpoint.send(body, false);
            response.setResultCode(CommonResult.Success);
    	} else {
    		response.setResultCode(CommonResult.Fail);
    	}
        return response;
    }
    
    @ApiOperation(value = "电子运单查询")
    @RequestMapping(value = "{terminalId}/electronWayBillQuery", method = RequestMethod.POST)
    @ResponseBody
    public ElectronWayBillQueryReply electronWayBillQuery(@PathVariable("terminalId") String terminalId, 
    		@ApiParam("电子运单ID列表，如果为空则查询所有电子运单") @RequestBody Integer[] idList) {
    	ElectronWayBillQuery body = new ElectronWayBillQuery();
        for (Integer id: idList) {
        	body.addElectronWayBill(new ElectronWayBill(id));
        }
        body.setHeader(new Header(JT808MessageCode.电子运单查询, terminalId));
        ElectronWayBillQueryReply response = (ElectronWayBillQueryReply) endpoint.send(body);
        return response;
    }
    
    @ApiOperation(value = "车外屏信息设置")
    @RequestMapping(value = "{terminalId}/screenInfoSetting", method = RequestMethod.POST)
    @ResponseBody
    public CommonResult screenInfoSetting(@PathVariable("terminalId") String terminalId, 
    		@RequestBody ScreenInfoSetting body) {
    	CommonResult response = new CommonResult();
    	Session session = sessionManager.findByTerminalId(terminalId);
    	if (session != null && session.getChannel().isWritable()) {
            body.setHeader(new Header(JT808MessageCode.车外屏信息设置, terminalId));
            endpoint.send(body, false);
            response.setResultCode(CommonResult.Success);
    	} else {
    		response.setResultCode(CommonResult.Fail);
    	}
        return response;
    }
    
    @ApiOperation(value = "车外屏信息删除")
    @RequestMapping(value = "{terminalId}/screenInfoRemove", method = RequestMethod.POST)
    @ResponseBody
    public CommonResult screenInfoRemove(@PathVariable("terminalId") String terminalId, 
    		@RequestBody Integer[] idList) {
    	CommonResult response = new CommonResult();
    	Session session = sessionManager.findByTerminalId(terminalId);
    	if (session != null && session.getChannel().isWritable()) {
        	ScreenInfoRemove body = new ScreenInfoRemove();
        	for (Integer id: idList) {
        		body.addScreenInfo(new ScreenInfo(id));
        	}
            body.setHeader(new Header(JT808MessageCode.车外屏信息删除, terminalId));
            endpoint.send(body, false);
            response.setResultCode(CommonResult.Success);
    	} else {
    		response.setResultCode(CommonResult.Fail);
    	}
        return response;
    }
    
    @ApiOperation(value = "车外屏信息查询")
    @RequestMapping(value = "{terminalId}/screenInfoQuery", method = RequestMethod.POST)
    @ResponseBody
    public ScreenInfoQueryReply screenInfoQuery(@PathVariable("terminalId") String terminalId, 
    		@ApiParam("车外屏信息ID列表，如果为空则查询所有车外屏信息") @RequestBody Integer[] idList) {
    	ScreenInfoQuery body = new ScreenInfoQuery();
    	for (Integer id: idList) {
    		body.addScreenInfo(new ScreenInfo(id));
    	}
        body.setHeader(new Header(JT808MessageCode.车外屏信息查询, terminalId));
        ScreenInfoQueryReply response = (ScreenInfoQueryReply) endpoint.send(body);
        return response;
    }
    
    @ApiOperation(value = "驾驶员身份信息设置")
    @RequestMapping(value = "{terminalId}/driverIdentityInfoSetting", method = RequestMethod.POST)
    @ResponseBody
    public CommonResult driverIdentityInfoSetting(@PathVariable("terminalId") String terminalId, 
    		@RequestBody DriverIdentityInfoSetting body) {
    	CommonResult response = new CommonResult();
    	Session session = sessionManager.findByTerminalId(terminalId);
    	if (session != null && session.getChannel().isWritable()) {
            body.setHeader(new Header(JT808MessageCode.驾驶员身份信息设置, terminalId));
            endpoint.send(body, false);
            response.setResultCode(CommonResult.Success);
    	} else {
    		response.setResultCode(CommonResult.Fail);
    	}
        return response;
    }
    
    @ApiOperation(value = "驾驶员身份信息删除")
    @RequestMapping(value = "{terminalId}/driverIdentityInfoRemove", method = RequestMethod.POST)
    @ResponseBody
    public CommonResult driverIdentityInfoRemove(@PathVariable("terminalId") String terminalId, 
    		@RequestBody Integer[] idList) {
    	CommonResult response = new CommonResult();
    	Session session = sessionManager.findByTerminalId(terminalId);
    	if (session != null && session.getChannel().isWritable()) {
        	DriverIdentityInfoRemove body = new DriverIdentityInfoRemove();
        	for (Integer id: idList) {
        		body.addDriverIdentityInfo(new DriverIdentityInfo(id));
        	}
            body.setHeader(new Header(JT808MessageCode.驾驶员身份信息删除, terminalId));
            endpoint.send(body, false);
            response.setResultCode(CommonResult.Success);
    	} else {
    		response.setResultCode(CommonResult.Fail);
    	}
        return response;
    }
    
    @ApiOperation(value = "驾驶员身份信息查询")
    @RequestMapping(value = "{terminalId}/driverIdentityInfoQuery", method = RequestMethod.POST)
    @ResponseBody
    public DriverIdentityInfoQueryReply driverIdentityInfoQuery(@PathVariable("terminalId") String terminalId, 
    		@ApiParam("驾驶员身份信息ID列表，如果为空则查询所有驾驶员身份信息") @RequestBody Integer[] idList) {
    	DriverIdentityInfoQuery body = new DriverIdentityInfoQuery();
    	for (Integer id: idList) {
    		body.addDriverIdentityInfo(new DriverIdentityInfo(id));
    	}
        body.setHeader(new Header(JT808MessageCode.车外屏信息查询, terminalId));
        DriverIdentityInfoQueryReply response = (DriverIdentityInfoQueryReply) endpoint.send(body);
        return response;
    }
}